package com.gateway.filter;

import com.client.common.vo.ClientResult;
import com.client.common.vo.ClientUser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gateway.client.AuthClient;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

/**
 * 安全认证过滤器
 * 功能已实现，放入容器中即可
 * @author dzh
 * @date 2023/1/30 16:25
 */
//@Component
@Order(0)
public class AuthGlobalFilter implements GlobalFilter {

    @Resource
    private AuthClient authClient;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        String userJson = getUserJson(exchange, chain);
        if (StringUtils.hasText(userJson)) {
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .header("x-request-user", userJson).build();

            return chain.filter(exchange.mutate().request(request).build());
        }

        if (!exchange.getResponse().isCommitted()) {

            ServerHttpResponse response = exchange.getResponse();

            ServerWebExchangeUtils.setResponseStatus(exchange, HttpStatus.FORBIDDEN);

//            return response.setComplete();
            return Mono.empty();
        }

        return Mono.empty();
    }

    public String getUserJson(ServerWebExchange exchange, GatewayFilterChain chain) {

        HttpHeaders headers = exchange.getRequest().getHeaders();
        String token = headers.entrySet().stream()
                .filter(h -> h.getKey().equalsIgnoreCase("x-request-token"))
                .findAny().map(e -> e.getValue().get(0)).orElse(null);

        if (!StringUtils.hasText(token)) {
            return null;
        }

        ClientResult<ClientUser> userClientResult = authClient.user(token);

        if (userClientResult == null || userClientResult.getData() == null) {
            return null;
        }

        ClientUser user = userClientResult.getData();
        try {
            return new ObjectMapper().writeValueAsString(user);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        }
    }
}
